package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.extities.pojo.ICP35;
import com.uduemc.biso.core.utils.RedisUtil;
import com.uduemc.biso.node.core.entities.HDomain;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.web.api.service.AsyncDomainService;
import com.uduemc.biso.node.web.api.service.CenterService;
import com.uduemc.biso.node.web.api.service.DomainService;
import com.uduemc.biso.node.web.api.service.NginxService;
import com.uduemc.biso.node.web.component.NginxOperate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;

@Service
@Slf4j
public class AsyncDomainServiceImpl implements AsyncDomainService {

    private final static String Redis_Key_AsyncBindDomain = "AsyncDomainServiceImpl.AsyncBindDomain";

    @Resource
    private CenterService centerServiceImpl;

    @Resource
    private GlobalProperties globalProperties;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private DomainService domainServiceImpl;

    @Resource
    private NginxService nginxServiceImpl;

    @Resource
    private NginxOperate nginxOperate;

    @Resource
    private HttpServletRequest request;

    @Override
    @Async
    public void asyncIcpDomain(HDomain hDomain) {
        String domain = hDomain.getDomainName();
        ICP35 icp35 = null;
        icp35 = centerServiceImpl.getIcpDomain(domain);
        if (icp35 == null || icp35.getResult() == -1) {
            return;
        }
        String KEY = globalProperties.getSiteRedisKey().getIcpDomainCachekey(domain);
        redisUtil.set(KEY, icp35, 3600 * 3);
        try {
            String remark = objectMapper.writeValueAsString(icp35);
            if (icp35.getResult() == 1) {
                hDomain.setStatus((short) 1);
                hDomain.setRemark(remark);
            } else if (icp35.getResult() == 0) {
                hDomain.setStatus((short) 2);
                hDomain.setRemark("");
            }
            domainServiceImpl.updateItem(hDomain);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    @Async
    public synchronized void asyncBindDomain() throws IOException {
        Integer v = (Integer) redisUtil.get(Redis_Key_AsyncBindDomain);
        if (v != null && v == 1) {
            return;
        }
        redisUtil.set(Redis_Key_AsyncBindDomain, 1, 1800L);
        int page = 1;
        int pageSize = 200;
        PageInfo<HDomain> pageInfo = null;
        do {
            if (pageInfo != null) {
                page = pageInfo.getNextPage();
            }
            pageInfo = domainServiceImpl.findPageInfo("", -1, (short) 1, (short) -1, 1, page, pageSize);
            List<HDomain> listHDomain = pageInfo.getList();

            if (CollectionUtil.isEmpty(listHDomain)) {
                break;
            }

            for (HDomain hDomain : listHDomain) {
                boolean bindDomain = nginxServiceImpl.bindDomain(hDomain, false);
                if (!bindDomain) {
                    log.error("异步，整个站点所有域名生成 nginx server 报错！错误 HDomain 数据：");
                    log.error(objectMapper.writeValueAsString(hDomain));
                    break;
                }

                if (!nginxOperate.boolTest()) {
                    log.error("测试 nginx 配置文件异常！异常内容：");
                    log.error(nginxOperate.test());
                    break;
                }
            }

        } while (pageInfo != null && pageInfo.isHasNextPage());
        redisUtil.del(Redis_Key_AsyncBindDomain);

        if (!nginxOperate.boolReload()) {
            log.error("重启Nginx失败！");
        }

    }

    @Override
    @Async
    public void bindDomain(HDomain hDomain) throws IOException {
        if (!nginxServiceImpl.bindDomain(hDomain)) {
            log.error("domainName", "通过 " + hDomain.getDomainName() + " 未能重新生成 nginx server 配置成功！");
        }
    }

    @Override
    @Async
    public void bindDomain(long hostId) throws IOException {
        if (!nginxServiceImpl.bindDomain(hostId)) {
            log.error("hostId", "通过 " + hostId + " 未能重新生成 nginx server 配置成功！");
        }
    }

}
